package org.spring.blog.controller.user;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.spring.blog.pojo.User;
import org.spring.blog.response.ResponseResult;
import org.spring.blog.response.ResponseState;
import org.spring.blog.service.IUserService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;

@RestController
@RequestMapping("/user")
public class UserApi {

    private final IUserService userService;

    public UserApi(IUserService userService) {
        this.userService = userService;
    }


    /**
     * 初始化管理员账户
     */
    @ApiOperation("初始化管理员账户")
    @ApiResponses({
            @ApiResponse(code = ResponseState.admin_is_register_code, message = ResponseState.admin_is_register_message),
            @ApiResponse(code = ResponseState.username_cant_empty_code, message = ResponseState.username_cant_empty_message),
            @ApiResponse(code = ResponseState.email_cant_empty_code, message = ResponseState.email_cant_empty_message),
            @ApiResponse(code = ResponseState.password_cant_empty_code, message = ResponseState.password_cant_empty_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @PostMapping("/admin_account")
    public ResponseResult initManagerAccount(@RequestBody User _user, HttpServletRequest _request) {

        return userService.initManagerAccount(_user, _request);
    }

    /**
     * 用户注册的接口
     *
     * @param _request     请求体
     * @param _user        用户信息对象
     * @param _verifyCode  验证码
     * @param _captchaCode 人类验证码
     * @return 自定义返回对象
     */
    @ApiOperation("用户注册的接口")
    @ApiResponses({
            @ApiResponse(code = ResponseState.username_cant_empty_code, message = ResponseState.username_cant_empty_message),
            @ApiResponse(code = ResponseState.username_not_unique_code, message = ResponseState.username_not_unique__message),
            @ApiResponse(code = ResponseState.email_cant_empty_code, message = ResponseState.email_cant_empty_message),
            @ApiResponse(code = ResponseState.email_form_error_code, message = ResponseState.email_form_error_message),
            @ApiResponse(code = ResponseState.email_not_unique_code, message = ResponseState.email_not_unique_message),
            @ApiResponse(code = ResponseState.verify_is_over_code, message = ResponseState.verify_is_over_message),
            @ApiResponse(code = ResponseState.verify_value_error_code, message = ResponseState.verify_value_error_message),
            @ApiResponse(code = ResponseState.captcha_is_over_code, message = ResponseState.captcha_is_over_message),
            @ApiResponse(code = ResponseState.captcha_value_error_code, message = ResponseState.captcha_value_error_message),
            @ApiResponse(code = ResponseState.password_cant_empty_code, message = ResponseState.password_cant_empty_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @PostMapping("/join_in")
    public ResponseResult register(HttpServletRequest _request, @RequestBody User _user,
                                   @RequestParam("verify_code") String _verifyCode,
                                   @RequestParam("captcha_code") String _captchaCode) {

        return userService.register(_request, _user, _verifyCode, _captchaCode);
    }

    /**
     * 用户登录
     *
     * @param _captcha 人类验证码信息
     * @param _user    用户信息
     * @return 自定义返回对象
     */
    @ApiOperation("用户登录")
    @ApiResponses({
            @ApiResponse(code = ResponseState.user_is_login_code, message = ResponseState.user_is_login_message),
            @ApiResponse(code = ResponseState.captcha_is_over_code, message = ResponseState.captcha_is_over_message),
            @ApiResponse(code = ResponseState.captcha_value_error_code, message = ResponseState.captcha_value_error_message),
            @ApiResponse(code = ResponseState.username_or_email_cant_empty_code, message = ResponseState.username_or_email_cant_empty_message),
            @ApiResponse(code = ResponseState.username_or_email_error_code, message = ResponseState.username_or_email_error_message),
            @ApiResponse(code = ResponseState.password_cant_empty_code, message = ResponseState.password_cant_empty_message),
            @ApiResponse(code = ResponseState.password_error_code, message = ResponseState.password_error_message),
            @ApiResponse(code = ResponseState.account_is_ban_code, message = ResponseState.account_is_ban_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @PostMapping("/login/{captcha}")
    public ResponseResult login(@PathVariable("captcha") String _captcha,
                                @RequestBody User _user,
                                @RequestParam(value = "from", required = false) String from) {
        return userService.login(_captcha, _user, from);
    }

    /**
     * 获取验证码
     */
    @ApiOperation("获取验证码")
    @GetMapping("/captcha")
    public void getCaptcha(HttpServletResponse _response) throws IOException, FontFormatException {
        userService.createCaptcha(_response);
    }

    /**
     * 发送邮件验证码
     *
     * @return 自定义返回对象
     */
    @ApiOperation("发送邮件验证码")
    @ApiResponses({
            @ApiResponse(code = ResponseState.email_is_unique_code, message = ResponseState.email_is_unique_message),
            @ApiResponse(code = ResponseState.email_not_unique_code, message = ResponseState.email_not_unique_message),
            @ApiResponse(code = ResponseState.send_verify_too_much_code, message = ResponseState.send_verify_too_much_message),
            @ApiResponse(code = ResponseState.send_verify_too_fast_code, message = ResponseState.send_verify_too_fast_message),
            @ApiResponse(code = ResponseState.email_form_error_code, message = ResponseState.email_form_error_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @GetMapping("/verity_code/{email}")
    public ResponseResult sendVerifyCodeByEmail(HttpServletRequest _request, @PathVariable("email") String email) {

        return userService.sendEmailVerifyCode(_request, email);
    }

    /**
     * 修改密码
     * 步骤
     * 1.用户登录
     * 2.使用用户的邮箱发送验证码
     * 3.用户填写验证码，和新密码
     * 4.服务器验证验证码和密码
     * 5.返回用户信息和更改服务器状态
     *
     * @param _user 用户信息
     * @return 自定义返回对象
     */
    @ApiOperation("修改密码")
    @ApiResponses({
            @ApiResponse(code = ResponseState.verify_is_over_code, message = ResponseState.verify_is_over_message),
            @ApiResponse(code = ResponseState.verify_value_error_code, message = ResponseState.verify_value_error_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
            @ApiResponse(code = ResponseState.failed_code, message = ResponseState.failed_message),
    })
    @PutMapping("/password/{verify_code}")
    public ResponseResult updatePasswordByUserEmail(@PathVariable("verify_code") String _verifyCode,
                                                    @RequestBody User _user) {
        return userService.updatePasswordByUserEmail(_verifyCode, _user);
    }

    /**
     * 获取用户信息
     *
     * @param userId 用户id
     * @return 自定义返回对象
     */
    @ApiOperation("获取用户信息")
    @ApiResponses({
            @ApiResponse(code = ResponseState.user_not_register_code, message = ResponseState.user_not_register_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @GetMapping("/user_info/{userId}")
    public ResponseResult getUserInfoById(@PathVariable("userId") String userId) {

        return userService.getUserInfoById(userId);
    }

    /**
     * 修改用户信息
     * <p>
     * /////////// 接口功能
     * // 允许修改的内容
     * 1.头像 avatar 2. userName, 3.sign
     * 4. password  5.email (密码 和 email 单独接口修改，应为需要进行身份和验证码验证）
     * <p>
     * ////////// 辅助接口
     * 为了用户体验和功能完善需要 提供接口检查 用户名和email是否重复
     * 应为登录可以用[username] [email] 需要保证唯一性
     * 增加接口方法 [checkUsernameUnique] [checkEmailUnique]
     * <p>
     * //////// 可扩展的接口功能
     * 可以借鉴qq, 当邮箱多次绑定，则前一次的解绑， 绑定新用户， 给用户更好的体验
     *
     * @param _user 用户信息
     * @return 自定义返回对象
     */
    @ApiOperation("修改用户信息")
    @ApiResponses({
            @ApiResponse(code = ResponseState.user_not_login_code, message = ResponseState.user_not_login_message),
            @ApiResponse(code = ResponseState.no_power_code, message = ResponseState.no_power_message),
            @ApiResponse(code = ResponseState.username_not_unique_code, message = ResponseState.username_not_unique__message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @PutMapping("/{userId}")
    public ResponseResult updateUserInfoByUserId(@PathVariable("userId") String userId, @RequestBody User _user) {
        return userService.updateUserInfoByUserId(userId, _user);
    }

    /**
     * 获取用户列表
     *
     * @param page 页码
     * @param size 页面大小
     * @return 自定义的返回结果对象
     */
    @ApiOperation("获取用户列表")
    @ApiResponses({
            @ApiResponse(code = ResponseState.error_403_code, message = ResponseState.error_403_message),
            @ApiResponse(code = ResponseState.user_not_login_code, message = ResponseState.user_not_login_message),
            @ApiResponse(code = ResponseState.no_power_code, message = ResponseState.no_power_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @PreAuthorize("@permission.admin()")
    @GetMapping("/list")
    public ResponseResult listUsers(@RequestParam("page") int page,
                                    @RequestParam("size") int size,
                                    @RequestParam(value = "userName", required = false) String _userName,
                                    @RequestParam(value = "email", required = false) String _email) {
        return userService.listUsers(page, size, _userName, _email);
    }

    /**
     * 删除用户接口，需要管理员权限
     *
     * @param userId 用户id
     * @return 自定义返回对象
     */
    @ApiOperation("删除用户接口，需要管理员权限")
    @ApiResponses({
            @ApiResponse(code = ResponseState.user_not_login_code, message = ResponseState.user_not_login_message),
            @ApiResponse(code = ResponseState.no_power_code, message = ResponseState.no_power_message),
            @ApiResponse(code = ResponseState.error_403_code, message = ResponseState.error_403_message),
            @ApiResponse(code = ResponseState.user_not_register_code, message = ResponseState.user_not_register_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @PreAuthorize("@permission.admin()")
    @DeleteMapping("/{userId}")
    public ResponseResult deleteUserByUserId(HttpServletRequest _request, HttpServletResponse _response, @PathVariable("userId") String userId) {
        return userService.deleteUserByUserId(_request, _response, userId);
    }

    /**
     * 检查邮箱的唯一性
     * ///////// 使用场景
     * 1. 用户注册 2. 修改邮箱
     *
     * @param email 邮箱地址
     * @return 自定义的返回对象
     */
    @ApiOperation("检查邮箱的唯一性")
    @ApiResponses({
            @ApiResponse(code = ResponseState.email_not_unique_code, message = ResponseState.email_not_unique_message),
            @ApiResponse(code = ResponseState.email_is_unique_code, message = ResponseState.email_is_unique_message)
    })
    @GetMapping("/email")
    public ResponseResult checkEmailUnique(@RequestParam("email") String email,
                                           @RequestParam("id") String _id) {
        return userService.checkEmailUnique(email, _id);
    }


    /**
     * 检查用户名的唯一性
     * ///////// 使用场景
     * 1. 用户注册 2. 修改username 昵称
     *
     * @param _username 用户输入的用户名
     * @return 自定义的返回对象
     */
    @ApiOperation("检查用户名的唯一性")
    @ApiResponses({
            @ApiResponse(code = ResponseState.username_not_unique_code, message = ResponseState.username_not_unique__message),
            @ApiResponse(code = ResponseState.username_is_unique_code, message = ResponseState.username_is_unique__message),
    })
    @GetMapping("/username")
    public ResponseResult checkUsernameUnique(@RequestParam("username") String _username,
                                              @RequestParam("id") String _id) {
        return userService.checkUsernameUnique(_username, _id);
    }


    /**
     * 修改邮箱
     * 1.登录状态 2.邮箱唯一
     *
     * @return 自定义返回对象
     */
    @ApiOperation("修改邮箱")
    @ApiResponses({
            @ApiResponse(code = ResponseState.user_not_login_code, message = ResponseState.user_not_login_message),
            @ApiResponse(code = ResponseState.verify_is_over_code, message = ResponseState.verify_is_over_message),
            @ApiResponse(code = ResponseState.verify_value_error_code, message = ResponseState.verify_value_error_message),
            @ApiResponse(code = ResponseState.email_not_unique_code, message = ResponseState.email_not_unique_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @PutMapping("/email")
    public ResponseResult updateEmail(@RequestParam("email") String _email,
                                      @RequestParam("verify_code") String _verifyCode) {
        return userService.updateEmail(_email, _verifyCode);
    }

    /**
     * 退出登录
     *
     * @return 自定义返回对象
     */
    @ApiOperation("退出登录")
    @ApiResponses({
            @ApiResponse(code = ResponseState.user_not_login_code, message = ResponseState.user_not_login_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @GetMapping("/logout")
    public ResponseResult logout() {
        return userService.logout();
    }


    /**
     * 获取登录着自己的信息
     *
     * @return 自定义返回对象
     */
    @ApiOperation("获取登录着自己的信息")
    @ApiResponses({
            @ApiResponse(code = ResponseState.user_not_login_code, message = ResponseState.user_not_login_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @GetMapping("/get-own-info")
    public ResponseResult getOwnInfo() {
        return userService.getOwnInfo();
    }

    /**
     * 获取二维码的请求方法
     *
     * @return 自定义返回对象
     */
    @ApiOperation("获取二维码的请求方法")
    @ApiResponses({
            @ApiResponse(code = ResponseState.user_not_login_code, message = ResponseState.user_not_login_message),
            @ApiResponse(code = ResponseState.too_fast_code, message = ResponseState.too_fast_message),
            @ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message),
    })
    @GetMapping("/pc-login-qr-code")
    public ResponseResult getPCLoginQrCode() {
        return userService.getPCLoginQrCode();
    }


    /**
     * 获取网站注册人数
     *
     * @return 自定义返回对象
     */
    @ApiOperation("获取网站注册人数")
    @ApiResponses(@ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message))
    @GetMapping("/register_count")
    public ResponseResult getRegisterCount() {
        return userService.getRegisterCount();
    }

    /**
     * 检查邮箱验证码是否正确
     *
     * @return 自定义返回对象
     */
    @ApiOperation("检查邮箱验证码是否正确")
    @ApiResponses(@ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message))
    @GetMapping("/check_email_code/{_email}/{_verifyCode}")
    public ResponseResult checkEmailVerifyCode(@PathVariable String _email, @PathVariable String _verifyCode) {
        return userService.checkEmailVerifyCode(_email, _verifyCode);
    }

    /**
     * 检查人类验证码是否正确
     *
     * @return 自定义返回对象
     */
    @ApiOperation("检查邮箱验证码是否正确")
    @ApiResponses(@ApiResponse(code = ResponseState.success_code, message = ResponseState.success_message))
    @GetMapping("/check_captcha_code/{_captchaCode}")
    public ResponseResult checkCaptchaCode(@PathVariable String _captchaCode) {
        return userService.checkCaptchaCode(_captchaCode);
    }
}
